package com.juku2024.juku.base

import android.content.Intent
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.juku2024.juku.dialog.CommonDialog
import com.juku2024.juku.dialog.CommonLoadingDialog
import com.juku2024.juku.dialog.DialogUtils
import com.juku2024.juku.network.api.Api
import com.juku2024.juku.network.retrofit.RetrofitUtils
import com.juku2024.juku.request.CheckAppRequest
import com.juku2024.juku.request.CommonRequest
import com.juku2024.juku.tools.*
import com.google.gson.Gson
import com.juku2024.juku.BuildConfig
import com.wanban.adutils.AdUtils
import com.juku2024.juku.DownloadPlayerActivity
import com.juku2024.juku.MainActivity
import com.juku2024.juku.OpenActivity
import com.juku2024.juku.R
import com.juku2024.juku.UpgradeActivity
import com.juku2024.juku.VideoDetailActivity
import com.juku2024.juku.dialog.UpdateDialog
import com.juku2024.juku.model.*
import com.juku2024.juku.network.NetStateChangeReceiver
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*


abstract class BaseActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        beforeOnCreate()
        super.onCreate(savedInstanceState)
        // 处理按home键退出后，再次进入会重启App
        if (ignoreHomeLauncher()) return
        setContentView(getLayoutResId())
        //防录屏截屏
        isScreenRecord()
        initView()
        bindEvent()
        init(savedInstanceState)
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    open fun isScreenRecord(isScreenRecord: Boolean = true){
        if (BuildConfig.DEBUG) return
        if (isScreenRecord) {
            if (this !is DownloadPlayerActivity) {
                window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
            }
        } else {
            window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
        }
    }

    open fun beforeOnCreate() {
        when (this) {
            is OpenActivity -> {
                UltimateBarX.statusBar(this).fitWindow(false).colorRes(R.color.black).apply()
                UltimateBarX.navigationBar(this).fitWindow(true).transparent().apply()
            }
            is UpgradeActivity -> {
                UltimateBarX.statusBar(this).fitWindow(true).transparent().apply()
                UltimateBarX.navigationBar(this).apply()
            }
            is VideoDetailActivity, is DownloadPlayerActivity -> {
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
//                window.statusBarColor = Color.BLACK
            }

            is MainActivity -> {
                UltimateBarX.statusBarOnly(this).fitWindow(true).color(Color.WHITE).apply()
            }

            else -> {
                UltimateBarX.statusBarOnly(this).fitWindow(true).color(Color.WHITE).apply()
            }
        }
    }

    abstract fun getLayoutResId(): Int

    open fun initView() {}

    open fun bindEvent() {}

    abstract fun init(savedInstanceState: Bundle?)

    /**
     * 当前Activity不可用
     */
    fun isActivityNotActive(): Boolean {
        return isFinishing || isDestroyed
    }

    /**
     * 获取ViewModel
     */
    fun <T : ViewModel> getViewModel(modelClass: Class<T>): T {
        return ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        )[modelClass]
    }

    /**
     * mainActivity默认是第一个页面，如果是从详情进入App，那么需要此处的判断
     */
    fun isNeedToMain(): Boolean {
        return AppUtils.getRunningTaskCount(this) <= 1
    }

    /**
     * 适配360
     */
    override fun getResources(): Resources? {
        val res = super.getResources()
        return AdapterScreenUtils.adaptScreen(this, res, 360)
    }

    override fun onResume() {
        super.onResume()
        AdUtils.onResume(this)
        // 注册网络监听
        NetStateChangeReceiver.registerReceiver(this)
    }

    override fun onPause() {
        super.onPause()
        AdUtils.onPause(this)
        // 取消
        NetStateChangeReceiver.unRegisterReceiver(this)
    }

    override fun onDestroy() {
        errorDialog?.dismiss()
        errorDialog = null
        loadingDialog?.dismiss()
        loadingDialog = null
        updateDialog?.dismiss()
        updateDialog = null
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }


    private var errorDialog: CommonDialog? = null
    open fun showErrorDialog(
        msg: String,
        yes: String?,
        yesClickListener: View.OnClickListener,
        no: String? = null,
        noClickListener: View.OnClickListener? = null
    ) {
        if (errorDialog == null) {
            errorDialog = if (noClickListener == null) {
                DialogUtils.showCommonConfirmDialog(this, msg, yes, yesClickListener)
            } else {
                DialogUtils.showCommonDialog(this, msg, yes, yesClickListener, no, noClickListener, false)
            }
        } else {
            if (noClickListener == null) {
                errorDialog?.showDialog(msg, yes, yesClickListener)
            } else {
                errorDialog?.showDialog(msg, yes, yesClickListener, no, noClickListener)
            }
        }
        errorDialog?.show()
    }

    open fun hideErrorDialog() {
        errorDialog?.dismiss()
    }

    private var loadingDialog: CommonLoadingDialog? = null
    fun showLoadingDialog() {
        if (loadingDialog == null) {
            loadingDialog = CommonLoadingDialog.showLoadingDialog(this)
        }
        if (loadingDialog?.isShowing == true) {
            return
        }
        loadingDialog?.show()
    }

    fun hideLoadingDialog() {
        loadingDialog?.dismiss()
    }

    /**
     * 防止按home退出后，再次进入app的时候重新启动
     */
    private fun ignoreHomeLauncher(): Boolean {
        try {
            if (!isTaskRoot) {
                val action = intent.action
                if (action != null && intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN == action) {
                    finish()
                    return true
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return false
    }




    var updateDialog: UpdateDialog? = null
    fun showUpgradeDialog(t: UpdateModel?) {
        if (isActivityNotActive() || t == null) return
        if (updateDialog == null) {
            updateDialog = UpdateDialog(this, t)
        }
        updateDialog?.show()
    }

    // 监听网络状态
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onNetworkEvent(event: NetworkEvent) {
        if (!event.isNetwork) return
        // 每次网络状态发生变化，都要检查下token
        checkAppToken()
        // 检查升级接口
        if (SPUtil.instance.latestNetAppVersion <= AppUtils.getVersionCode()) { // 无需升级
            return
        }
        // 判断是否需要升级
        if (updateDialog?.isShowing == true) { // 升级框正在展示
            return
        }

        // 检查升级
        doUpgradeObservable()
    }

    private fun checkAppToken() {
        val token = SPUtil.instance.token
        if (TextUtils.isEmpty(token)) {
            // token无效，请求token
            doHttpGetToken()
            return
        }
        val tokenExpireTime = SPUtil.instance.tokenExpireTime
        if (System.currentTimeMillis() < tokenExpireTime) {
            // token在有效期内
            return
        }
        // token过期，请求token
        doHttpGetToken()
    }

    private fun doHttpGetToken() {
        val appId = AppUtils.method03()
        val appKey = AppUtils.method04()
        val zone = TimeZone.getTimeZone("UTC+8")
        val cal = Calendar.getInstance(zone)
        val timestamp = cal.timeInMillis
        val sign = MD5Utils.getMD5String(AppUtils.method05(), appId, appKey, timestamp.toString(), AppUtils.method06())
        val request = CheckAppRequest(appId, timestamp, sign)
        RetrofitUtils.instance.getApi(Api::class.java).checkAppObservable(request)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                if (TextUtils.isEmpty(it.body) || TextUtils.isEmpty(it.ticket)) {
                    return@subscribe
                }
                // 用rsa的私钥去解密ticket，获得aes的秘钥
                val aesKey = EncryptionUtils.rsaDecrypt(it.ticket)
                if (TextUtils.isEmpty(aesKey)) {
                    return@subscribe
                }
                val jsonBody = EncryptionUtils.aesDecrypt(it.body, aesKey)
                val gson = Gson()
                val checkResponse = gson.fromJson(jsonBody, CheckResponse::class.java)
                if (checkResponse.data == null || checkResponse.data?.length != 32) {
                    return@subscribe
                }
                // 设置秘钥，主要是加密上传参数用
                // 更新缓存的数据
                val updateTime = System.currentTimeMillis() + checkResponse.duration * 1000
                SPUtil.instance.tokenExpireTime = updateTime
                SPUtil.instance.token = checkResponse.data?:""
                SPUtil.instance.tf = checkResponse.tf
                if (TextUtils.isEmpty(SPUtil.instance.userId) && !TextUtils.isEmpty(checkResponse.uid)) {
                    SPUtil.instance.userId = checkResponse.uid?:""
                }
            }, {
                it?.printStackTrace()
            }).isDisposed
    }


    private fun doUpgradeObservable() {
        val appId = AppUtils.method03()
        val appKey = AppUtils.method04()
        val zone = TimeZone.getTimeZone("UTC+8")
        val cal = Calendar.getInstance(zone)
        val timestamp = cal.timeInMillis
        val sign = MD5Utils.getMD5String(appId, appKey, timestamp, AppUtils.method06())
        val params = CheckAppRequest(appId, timestamp, sign)
        val body = Gson().toJson(params)
        val commonRequest = CommonRequest()
        commonRequest.body = EncryptionUtils.aesEncrypt(body)
        commonRequest.ticket = EncryptionUtils.rsaEncrypt()
        RetrofitUtils.instance.getApi(Api::class.java).getUpdateV2Observable(appId, commonRequest)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ result ->
                if (result?.body == null || result.ticket == null) {
                    return@subscribe
                }
                val aesKey = EncryptionUtils.rsaDecrypt(result.ticket)
                val upgradeModelJson = EncryptionUtils.aesDecrypt(result.body, aesKey)
                if (aesKey == null || upgradeModelJson == null) {
                    return@subscribe
                }
                var updateModel = Gson().fromJson(upgradeModelJson, UpgradeResponse::class.java)?.data
//                if (updateModel == null && BuildConfig.DEBUG) {
//                    updateModel = UpdateModel()
//                    updateModel.versionCode = "1.99999"
//                    updateModel.versionNumber = 999
//                    updateModel.title = "测试升级来了"
//                    updateModel.txt = "测试升级来了  全局检测网络之后的弹窗"
//                    updateModel.btnTitle = "测试升级"
//                    updateModel.downloadApk = true
//                    updateModel.url = "http://img.shiyifacai.com/download/xiaoyin2023.note.1.9.apk"
//                }
                if (updateModel == null) {
                    return@subscribe
                }
                val isNeedUpgrade = updateModel.versionNumber > AppUtils.getVersionCode()
                SPUtil.instance.latestNetAppVersion = updateModel.versionNumber
                if (isNeedUpgrade) { // 需要更新
//                    AnalysisUtils.analysis(AnalysisConstants.EVENT_UPGRADE_V2, AnalysisConstants.KEY_SHOW_DIALOG, javaClass.simpleName)
//                    showUpgradeDialog(updateModel)

                    val typeStr = if (updateModel.type == 0) "弹窗" else "页面"
                    AnalysisUtils.analysis(AnalysisConstants.EVENT_UPGRADE, AnalysisConstants.KEY_SHOW_DIALOG, javaClass.simpleName + " -> $typeStr")
                    if (updateModel.type == 0) { // 弹窗
                        showUpgradeDialog(updateModel)
                    } else { // 页面
                        val intent = Intent(this@BaseActivity, UpgradeActivity::class.java)
                        intent.putExtra(Constants.INTENT_KEY_UPDATE,updateModel)
                        startActivity(intent)
                    }
                }
            }, {
                it?.printStackTrace()
            }).isDisposed
    }



}